package dao

import (
	"log"
	"time"

	"gitee.com/legend9999/publisher/modle"
	"github.com/jinzhu/gorm"
)

type BookDAO int

func (b *BookDAO) Create(userID uint, book *modle.Book) error {
	book.Stage = modle.STAGE_1
	book.Status = modle.S1_1
	begin := DB.Begin()
	if err := begin.Create(book).Error; err != nil {
		log.Printf("create book%+v err:%s", book, err)
		begin.Rollback()
		return err
	}
	var (
		bookStatus             modle.BookStatus
		bookStatusList         []modle.BookStatus
		startStatus, endStatus modle.Status
	)
	for i := modle.STAGE_1; i <= modle.STAGE_4; i++ {
		if i == modle.STAGE_1 {
			startStatus, endStatus = modle.S1_1, modle.S1_7
		} else if i == modle.STAGE_2 {
			startStatus, endStatus = modle.S2_1, modle.S2_3
		} else if i == modle.STAGE_3 {
			startStatus, endStatus = modle.S3_1, modle.S3_3
		} else if i == modle.STAGE_4 {
			startStatus, endStatus = modle.S4_1, modle.S4_1
		}
		for j := startStatus; j <= endStatus; j++ {
			bookStatus = modle.BookStatus{
				BookID: book.ID,
				UserID: userID,
				Stage:  i,
				Status: j,
			}
			bookStatusList = append(bookStatusList, bookStatus)
		}
	}
	for _, bookStage := range bookStatusList {
		if err := begin.Create(&bookStage).Error; err != nil {
			log.Printf("create bookStatus%+v err:%s", bookStage, err)
			begin.Rollback()
			return err
		}
	}
	begin.Commit()
	return nil
}
func (b *BookDAO) Update(book *modle.Book) error {
	if err := DB.Save(book).Error; err != nil {
		log.Printf("update book%+v err:%s", book, err)
		return err
	}
	return nil
}
func (b *BookDAO) Query(id int64) (*modle.Book, error) {
	var book modle.Book
	if err := DB.Preload("Statuses.User").Preload("Statuses").Where("id = ?", id).First(&book).Error; err != nil {
		log.Printf("query book id:%+d err:%s", id, err)
		return nil, err
	}
	return &book, nil
}
func (b *BookDAO) Delete(id int64) error {
	var book modle.Book
	if err := DB.Delete(&book, "id = ?", id).Error; err != nil {
		log.Printf("Delete book id:%+d err:%s", id, err)
		return err
	}
	return nil
}
func (b *BookDAO) Page(page *Page, book *modle.Book) (err error) {
	filter := func(db *gorm.DB) *gorm.DB {
		if book.CustomID != "" {
			db = db.Where("custom_id = ?", book.CustomID)
		}
		if book.Name != "" {
			db = db.Where("name like ?", "%"+book.Name+"%")
		}
		if book.Stage != 0 {
			db = db.Where("stage = ?", book.Stage)
		} else {
			db = db.Where("stage != ?", modle.STAGE_4)
		}
		if book.FenShe != "" {
			db = db.Where("fen_she like ?", "%"+book.FenShe+"%")
		}
		if book.Editor != "" {
			db = db.Where("editor like ?", "%"+book.Editor+"%")
		}
		if book.WenAn != "" {
			db = db.Where("wen_an like ?", "%"+book.WenAn+"%")
		}
		if book.CaiCha != "" {
			db = db.Where("cai_cha like ?", "%"+book.CaiCha+"%")
		}
		if book.Status != 0 {
			db = db.Where("status = ?", book.Status)
		}
		return db
	}
	if DB.Model(&modle.Book{}).Scopes(filter).Count(&page.RecordCount).Error != nil {
		return DBErr
	}
	var books []modle.Book
	err = DB.Scopes(filter).Preload("Statuses.User").Preload("Statuses").Order("custom_id desc").Limit(page.PageSize).Offset(page.PageSize * (page.PageNum - 1)).Find(&books).Error
	if err != nil {
		return NotFoundErr
	}
	page.Data = books
	return nil
}

func (b *BookDAO) All() (result []modle.Book, err error) {
	var books []modle.Book
	err = DB.Preload("Statuses.User").Preload("Statuses").Order("custom_id desc").Find(&books).Error
	if err != nil {
		return nil, NotFoundErr
	}
	return books, nil
}
func (b *BookDAO) QueryByCreateTime(createTime *time.Time) (result []modle.Book, err error) {
	var books []modle.Book
	err = DB.Where("created_at > ?", createTime).Find(&books).Error
	if err != nil {
		return nil, NotFoundErr
	}
	return books, nil
}
